{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 引用包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
    "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# This Python 3 environment comes with many helpful analytics libraries installed\n",
    "# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n",
    "# For example, here's several helpful packages to load in \n",
    "\n",
    "import numpy as np # linear algebra\n",
    "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n",
    "\n",
    "# Input data files are available in the \"../input/\" directory.\n",
    "# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n",
    "\n",
    "import os\n",
    "for dirname, _, filenames in os.walk('/kaggle/input'):\n",
    "    for filename in filenames:\n",
    "        print(os.path.join(dirname, filename))\n",
    "\n",
    "# Any results you write to the current directory are saved as output."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据导入"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "_cell_guid": "79c7e3d0-c299-4dcb-8224-4455121ee9b0",
    "_uuid": "d629ff2d2480ee46fbb7e2d37f6b5fab8052498a"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>color</th>\n",
       "      <th>date</th>\n",
       "      <th>feature_1</th>\n",
       "      <th>feature_2</th>\n",
       "      <th>size</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>country</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>JP</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-01-06</td>\n",
       "      <td>-1.234449</td>\n",
       "      <td>-0.133232</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">B</th>\n",
       "      <th>CN</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-01-13</td>\n",
       "      <td>1.308935</td>\n",
       "      <td>-0.493569</td>\n",
       "      <td>M</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-01-20</td>\n",
       "      <td>0.041672</td>\n",
       "      <td>1.014697</td>\n",
       "      <td>L</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-01-27</td>\n",
       "      <td>-0.203778</td>\n",
       "      <td>1.742654</td>\n",
       "      <td>M</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <th>US</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-02-03</td>\n",
       "      <td>0.419852</td>\n",
       "      <td>-2.964561</td>\n",
       "      <td>L</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>CN</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-02-10</td>\n",
       "      <td>2.350862</td>\n",
       "      <td>-1.895651</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <th>CN</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-02-17</td>\n",
       "      <td>-0.649887</td>\n",
       "      <td>-0.187894</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>CA</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-02-24</td>\n",
       "      <td>0.912200</td>\n",
       "      <td>0.782471</td>\n",
       "      <td>XL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">C</th>\n",
       "      <th>JP</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-03-03</td>\n",
       "      <td>-1.295436</td>\n",
       "      <td>0.416840</td>\n",
       "      <td>XL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CA</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-03-10</td>\n",
       "      <td>0.500633</td>\n",
       "      <td>2.827345</td>\n",
       "      <td>M</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               color       date  feature_1  feature_2 size\n",
       "class country                                             \n",
       "A     JP       black 2019-01-06  -1.234449  -0.133232    S\n",
       "B     CN       white 2019-01-13   1.308935  -0.493569    M\n",
       "      US       black 2019-01-20   0.041672   1.014697    L\n",
       "      US       white 2019-01-27  -0.203778   1.742654    M\n",
       "C     US       black 2019-02-03   0.419852  -2.964561    L\n",
       "A     CN       white 2019-02-10   2.350862  -1.895651    S\n",
       "B     CN       black 2019-02-17  -0.649887  -0.187894    S\n",
       "A     CA       white 2019-02-24   0.912200   0.782471   XL\n",
       "C     JP       black 2019-03-03  -1.295436   0.416840   XL\n",
       "      CA       white 2019-03-10   0.500633   2.827345    M"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_dict = {'color' : ['black', 'white', 'black', 'white', 'black',\n",
    "                      'white', 'black', 'white', 'black', 'white'],\n",
    "            'size' : ['S','M','L','M','L','S','S','XL','XL','M'],\n",
    "        'date':pd.date_range('1/1/2019',periods=10, freq='W' ),\n",
    "            'feature_1': np.random.randn(10),\n",
    "            'feature_2': np.random.normal(0.5, 2, 10)}\n",
    "array=[['A','B','B','B','C','A','B','A','C','C'],['JP','CN','US','US','US','CN','CN','CA','JP','CA']]\n",
    "                                                 \n",
    "index = pd.MultiIndex.from_arrays(array, names=['class', 'country'])\n",
    "data_df = pd.DataFrame(data_dict,index=index)\n",
    "data_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 分组\n",
    "将dataframe根据size进行分组，得到group_1。在这里我们将GroupBy对象转换list后输出。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('L',                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "B     US       black 2019-01-20  -1.204530   2.331003    L\n",
      "C     US       black 2019-02-03  -0.475149   2.455877    L)\n",
      "('M',                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "B     CN       white 2019-01-13   0.354512  -0.106245    M\n",
      "      US       white 2019-01-27   0.640886   3.105454    M\n",
      "C     CA       white 2019-03-10   0.471399   1.102412    M)\n",
      "('S',                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "A     JP       black 2019-01-06   0.599631   1.029602    S\n",
      "      CN       white 2019-02-10   0.024186   2.412876    S\n",
      "B     CN       black 2019-02-17   3.110097   0.678240    S)\n",
      "('XL',                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "A     CA       white 2019-02-24   0.890249   1.522595   XL\n",
      "C     JP       black 2019-03-03  -1.216877   2.321393   XL)\n"
     ]
    }
   ],
   "source": [
    "group_1 = data_df.groupby('size')\n",
    "for i in list(group_1):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对GroupBy对象进行分组运算，如sum(),非数值数据则不进行分组运算。将计算得到的数据添加表头前缀后输出\n",
    "     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sum_feature_1</th>\n",
       "      <th>sum_feature_2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>size</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>L</th>\n",
       "      <td>-1.679679</td>\n",
       "      <td>4.786880</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>M</th>\n",
       "      <td>1.466797</td>\n",
       "      <td>4.101621</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S</th>\n",
       "      <td>3.733914</td>\n",
       "      <td>4.120718</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>XL</th>\n",
       "      <td>-0.326628</td>\n",
       "      <td>3.843988</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      sum_feature_1  sum_feature_2\n",
       "size                              \n",
       "L         -1.679679       4.786880\n",
       "M          1.466797       4.101621\n",
       "S          3.733914       4.120718\n",
       "XL        -0.326628       3.843988"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "group_1.sum().add_prefix('sum_')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "根据size进行分组后获得所有size值为M的行向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>color</th>\n",
       "      <th>date</th>\n",
       "      <th>feature_1</th>\n",
       "      <th>feature_2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>country</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td rowspan=\"2\" valign=\"top\">B</td>\n",
       "      <td>CN</td>\n",
       "      <td>white</td>\n",
       "      <td>2019-01-13</td>\n",
       "      <td>1.735991</td>\n",
       "      <td>0.383047</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>US</td>\n",
       "      <td>white</td>\n",
       "      <td>2019-01-27</td>\n",
       "      <td>-0.847715</td>\n",
       "      <td>-2.327769</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>C</td>\n",
       "      <td>CA</td>\n",
       "      <td>white</td>\n",
       "      <td>2019-03-10</td>\n",
       "      <td>-0.818303</td>\n",
       "      <td>1.317979</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               color       date  feature_1  feature_2\n",
       "class country                                        \n",
       "B     CN       white 2019-01-13   1.735991   0.383047\n",
       "      US       white 2019-01-27  -0.847715  -2.327769\n",
       "C     CA       white 2019-03-10  -0.818303   1.317979"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "group_1.get_group('M')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将dataframe根据size和color两个列标签进行多重分组，得到group_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(('L', 'black'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "B     US       black 2019-01-20   0.041672   1.014697    L\n",
      "C     US       black 2019-02-03   0.419852  -2.964561    L)\n",
      "(('M', 'white'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "B     CN       white 2019-01-13   1.308935  -0.493569    M\n",
      "      US       white 2019-01-27  -0.203778   1.742654    M\n",
      "C     CA       white 2019-03-10   0.500633   2.827345    M)\n",
      "(('S', 'black'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "A     JP       black 2019-01-06  -1.234449  -0.133232    S\n",
      "B     CN       black 2019-02-17  -0.649887  -0.187894    S)\n",
      "(('S', 'white'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "A     CN       white 2019-02-10   2.350862  -1.895651    S)\n",
      "(('XL', 'black'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "C     JP       black 2019-03-03  -1.295436    0.41684   XL)\n",
      "(('XL', 'white'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "A     CA       white 2019-02-24     0.9122   0.782471   XL)\n"
     ]
    }
   ],
   "source": [
    "group_2 = data_df.groupby(['size', 'color'])\n",
    "for i in list(group_2):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对分组后的数据size函数获得组别个数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "size\n",
      "L     2\n",
      "M     3\n",
      "S     3\n",
      "XL    2\n",
      "dtype: int64\n",
      "size  color\n",
      "L     black    2\n",
      "M     white    3\n",
      "S     black    2\n",
      "      white    1\n",
      "XL    black    1\n",
      "      white    1\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(group_1.size())\n",
    "print(group_2.size())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "此外还可以利用函数进行分组。注意到groupby函数中axis=1对列进行分组，axis=0对行进行分组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('feature',                feature_1  feature_2\n",
      "class country                      \n",
      "A     JP        0.599631   1.029602\n",
      "B     CN        0.354512  -0.106245\n",
      "      US       -1.204530   2.331003\n",
      "      US        0.640886   3.105454\n",
      "C     US       -0.475149   2.455877\n",
      "A     CN        0.024186   2.412876\n",
      "B     CN        3.110097   0.678240\n",
      "A     CA        0.890249   1.522595\n",
      "C     JP       -1.216877   2.321393\n",
      "      CA        0.471399   1.102412)\n",
      "('other',                color       date size\n",
      "class country                       \n",
      "A     JP       black 2019-01-06    S\n",
      "B     CN       white 2019-01-13    M\n",
      "      US       black 2019-01-20    L\n",
      "      US       white 2019-01-27    M\n",
      "C     US       black 2019-02-03    L\n",
      "A     CN       white 2019-02-10    S\n",
      "B     CN       black 2019-02-17    S\n",
      "A     CA       white 2019-02-24   XL\n",
      "C     JP       black 2019-03-03   XL\n",
      "      CA       white 2019-03-10    M)\n"
     ]
    }
   ],
   "source": [
    "def get_letter_type(letter):\n",
    "    if 'feature' in letter:\n",
    "        return 'feature'\n",
    "    else:\n",
    "        return 'other'\n",
    "    \n",
    "for i in list(data_df.groupby(get_letter_type, axis=1)):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "分组对象除了列标签之外，还可以是索引，其中用不同的level值来区分多重索引。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(('A', 'CA'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "A     CA       white 2019-02-24   0.890249   1.522595   XL)\n",
      "(('A', 'CN'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "A     CN       white 2019-02-10   0.024186   2.412876    S)\n",
      "(('A', 'JP'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "A     JP       black 2019-01-06   0.599631   1.029602    S)\n",
      "(('B', 'CN'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "B     CN       white 2019-01-13   0.354512  -0.106245    M\n",
      "      CN       black 2019-02-17   3.110097   0.678240    S)\n",
      "(('B', 'US'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "B     US       black 2019-01-20  -1.204530   2.331003    L\n",
      "      US       white 2019-01-27   0.640886   3.105454    M)\n",
      "(('C', 'CA'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "C     CA       white 2019-03-10   0.471399   1.102412    M)\n",
      "(('C', 'JP'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "C     JP       black 2019-03-03  -1.216877   2.321393   XL)\n",
      "(('C', 'US'),                color       date  feature_1  feature_2 size\n",
      "class country                                             \n",
      "C     US       black 2019-02-03  -0.475149   2.455877    L)\n"
     ]
    }
   ],
   "source": [
    "for i in list(data_df.groupby(level=[0,1])):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "DataFrame可以根据列标签和索引两者同时分组,分组后可以在不同组间进行迭代"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('CA', 'white')\n",
      "               color size       date  feature_1  feature_2\n",
      "class country                                             \n",
      "A     CA       white   XL 2019-02-24   0.412967   1.196859\n",
      "C     CA       white    M 2019-03-10  -0.818303   1.317979\n",
      "('CN', 'black')\n",
      "               color size       date  feature_1  feature_2\n",
      "class country                                             \n",
      "B     CN       black    S 2019-02-17  -0.058021  -2.420962\n",
      "('CN', 'white')\n",
      "               color size       date  feature_1  feature_2\n",
      "class country                                             \n",
      "B     CN       white    M 2019-01-13   1.735991   0.383047\n",
      "A     CN       white    S 2019-02-10   0.282515   3.156525\n",
      "('JP', 'black')\n",
      "               color size       date  feature_1  feature_2\n",
      "class country                                             \n",
      "A     JP       black    S 2019-01-06   0.997065  -1.018255\n",
      "C     JP       black   XL 2019-03-03   0.513201  -3.266357\n",
      "('US', 'black')\n",
      "               color size       date  feature_1  feature_2\n",
      "class country                                             \n",
      "B     US       black    L 2019-01-20  -0.547211   0.693104\n",
      "C     US       black    L 2019-02-03  -0.245918   4.444044\n",
      "('US', 'white')\n",
      "               color size       date  feature_1  feature_2\n",
      "class country                                             \n",
      "B     US       white    M 2019-01-27  -0.847715  -2.327769\n"
     ]
    }
   ],
   "source": [
    "group_3=df.groupby(['country','color'])\n",
    "for name, group in group_3:\n",
    "    print(name)\n",
    "    print(group)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当GroupBy对象被建立后，我们可以用agg函数对分组后的数据进行计算。下例中计算了group_3中feature_1的最大值和feature_2的均值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>feature_1</th>\n",
       "      <th>feature_2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>size</th>\n",
       "      <th>color</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>L</th>\n",
       "      <th>black</th>\n",
       "      <td>-1.204530</td>\n",
       "      <td>2.393440</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>M</th>\n",
       "      <th>white</th>\n",
       "      <td>0.354512</td>\n",
       "      <td>1.367207</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">S</th>\n",
       "      <th>black</th>\n",
       "      <td>0.599631</td>\n",
       "      <td>0.853921</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>white</th>\n",
       "      <td>0.024186</td>\n",
       "      <td>2.412876</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">XL</th>\n",
       "      <th>black</th>\n",
       "      <td>-1.216877</td>\n",
       "      <td>2.321393</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>white</th>\n",
       "      <td>0.890249</td>\n",
       "      <td>1.522595</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            feature_1  feature_2\n",
       "size color                      \n",
       "L    black  -1.204530   2.393440\n",
       "M    white   0.354512   1.367207\n",
       "S    black   0.599631   0.853921\n",
       "     white   0.024186   2.412876\n",
       "XL   black  -1.216877   2.321393\n",
       "     white   0.890249   1.522595"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "group_2.agg({'feature_1' : np.min,'feature_2' : np.mean})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来我们使用transform函数对groupby对象进行变换，transform的计算结果和原始数据的形状保持一致。下例中我们自定义了函数data_range来获得根据size分组后各个值的范围。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>date</th>\n",
       "      <th>feature_1</th>\n",
       "      <th>feature_2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>country</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>JP</th>\n",
       "      <td>42 days</td>\n",
       "      <td>3.085912</td>\n",
       "      <td>1.734636</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">B</th>\n",
       "      <th>CN</th>\n",
       "      <td>56 days</td>\n",
       "      <td>0.286375</td>\n",
       "      <td>3.211699</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>14 days</td>\n",
       "      <td>0.729382</td>\n",
       "      <td>0.124874</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>56 days</td>\n",
       "      <td>0.286375</td>\n",
       "      <td>3.211699</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <th>US</th>\n",
       "      <td>14 days</td>\n",
       "      <td>0.729382</td>\n",
       "      <td>0.124874</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>CN</th>\n",
       "      <td>42 days</td>\n",
       "      <td>3.085912</td>\n",
       "      <td>1.734636</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <th>CN</th>\n",
       "      <td>42 days</td>\n",
       "      <td>3.085912</td>\n",
       "      <td>1.734636</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>CA</th>\n",
       "      <td>7 days</td>\n",
       "      <td>2.107125</td>\n",
       "      <td>0.798798</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">C</th>\n",
       "      <th>JP</th>\n",
       "      <td>7 days</td>\n",
       "      <td>2.107125</td>\n",
       "      <td>0.798798</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CA</th>\n",
       "      <td>56 days</td>\n",
       "      <td>0.286375</td>\n",
       "      <td>3.211699</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 date  feature_1  feature_2\n",
       "class country                              \n",
       "A     JP      42 days   3.085912   1.734636\n",
       "B     CN      56 days   0.286375   3.211699\n",
       "      US      14 days   0.729382   0.124874\n",
       "      US      56 days   0.286375   3.211699\n",
       "C     US      14 days   0.729382   0.124874\n",
       "A     CN      42 days   3.085912   1.734636\n",
       "B     CN      42 days   3.085912   1.734636\n",
       "A     CA       7 days   2.107125   0.798798\n",
       "C     JP       7 days   2.107125   0.798798\n",
       "      CA      56 days   0.286375   3.211699"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_range = lambda x: x.max() - x.min()\n",
    "data_df.groupby('size').transform(data_range)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "另外我们还常常通过transform函数将缺失值替换为组间平均值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py:399: PerformanceWarning: indexing past lexsort depth may impact performance.\n",
      "  user_expressions, allow_stdin)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>feature_1</th>\n",
       "      <th>feature_2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>country</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>JP</th>\n",
       "      <td>-0.023671</td>\n",
       "      <td>-0.409491</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">B</th>\n",
       "      <th>CN</th>\n",
       "      <td>-0.091596</td>\n",
       "      <td>-1.399647</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>1.085396</td>\n",
       "      <td>2.245660</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>-0.127399</td>\n",
       "      <td>-1.747656</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <th>US</th>\n",
       "      <td>-2.046202</td>\n",
       "      <td>3.475487</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>CN</th>\n",
       "      <td>-1.076002</td>\n",
       "      <td>2.705517</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <th>CN</th>\n",
       "      <td>0.184117</td>\n",
       "      <td>2.913971</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>CA</th>\n",
       "      <td>0.601222</td>\n",
       "      <td>-2.098025</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">C</th>\n",
       "      <th>JP</th>\n",
       "      <td>-0.009375</td>\n",
       "      <td>-3.623235</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CA</th>\n",
       "      <td>-0.055794</td>\n",
       "      <td>-1.051638</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               feature_1  feature_2\n",
       "class country                      \n",
       "A     JP       -0.023671  -0.409491\n",
       "B     CN       -0.091596  -1.399647\n",
       "      US        1.085396   2.245660\n",
       "      US       -0.127399  -1.747656\n",
       "C     US       -2.046202   3.475487\n",
       "A     CN       -1.076002   2.705517\n",
       "B     CN        0.184117   2.913971\n",
       "A     CA        0.601222  -2.098025\n",
       "C     JP       -0.009375  -3.623235\n",
       "      CA       -0.055794  -1.051638"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df.iloc[1, 2:4] = np.NaN\n",
    "group_4 = data_df.groupby('size')\n",
    "f = lambda x: x.fillna(x.mean())\n",
    "df_trans = group_4.transform(f)\n",
    "df_trans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>color</th>\n",
       "      <th>date</th>\n",
       "      <th>feature_1</th>\n",
       "      <th>feature_2</th>\n",
       "      <th>size</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>country</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>JP</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-01-06</td>\n",
       "      <td>-0.023671</td>\n",
       "      <td>-0.409491</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">B</th>\n",
       "      <th>CN</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-01-13</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>M</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-01-20</td>\n",
       "      <td>1.085396</td>\n",
       "      <td>2.245660</td>\n",
       "      <td>L</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-01-27</td>\n",
       "      <td>-0.127399</td>\n",
       "      <td>-1.747656</td>\n",
       "      <td>M</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <th>US</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-02-03</td>\n",
       "      <td>-2.046202</td>\n",
       "      <td>3.475487</td>\n",
       "      <td>L</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>CN</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-02-10</td>\n",
       "      <td>-1.076002</td>\n",
       "      <td>2.705517</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <th>CN</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-02-17</td>\n",
       "      <td>0.184117</td>\n",
       "      <td>2.913971</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>CA</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-02-24</td>\n",
       "      <td>0.601222</td>\n",
       "      <td>-2.098025</td>\n",
       "      <td>XL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">C</th>\n",
       "      <th>JP</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-03-03</td>\n",
       "      <td>-0.009375</td>\n",
       "      <td>-3.623235</td>\n",
       "      <td>XL</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CA</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-03-10</td>\n",
       "      <td>-0.055794</td>\n",
       "      <td>-1.051638</td>\n",
       "      <td>M</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               color       date  feature_1  feature_2 size\n",
       "class country                                             \n",
       "A     JP       black 2019-01-06  -0.023671  -0.409491    S\n",
       "B     CN       white 2019-01-13        NaN        NaN    M\n",
       "      US       black 2019-01-20   1.085396   2.245660    L\n",
       "      US       white 2019-01-27  -0.127399  -1.747656    M\n",
       "C     US       black 2019-02-03  -2.046202   3.475487    L\n",
       "A     CN       white 2019-02-10  -1.076002   2.705517    S\n",
       "B     CN       black 2019-02-17   0.184117   2.913971    S\n",
       "A     CA       white 2019-02-24   0.601222  -2.098025   XL\n",
       "C     JP       black 2019-03-03  -0.009375  -3.623235   XL\n",
       "      CA       white 2019-03-10  -0.055794  -1.051638    M"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "根据列标签color进行分组后对列标签feature_1使用rolling方法,滚动计算最新的三个值的平均。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "color  class  country\n",
       "black  A      JP              NaN\n",
       "       B      US              NaN\n",
       "       C      US        -0.257642\n",
       "       B      CN        -0.062787\n",
       "       C      JP        -0.508490\n",
       "white  B      CN              NaN\n",
       "              US              NaN\n",
       "       A      CN         1.152006\n",
       "              CA         1.019761\n",
       "       C      CA         1.254565\n",
       "Name: feature_1, dtype: float64"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df.groupby('color').rolling(3).feature_1.mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "expanding函数会对给定的操作（如下例中的sum）进行叠加"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "color  class  country\n",
       "black  A      JP              NaN\n",
       "       B      US              NaN\n",
       "       C      US        -0.772925\n",
       "       B      CN        -1.422812\n",
       "       C      JP        -2.718247\n",
       "white  B      CN              NaN\n",
       "              US              NaN\n",
       "       A      CN         3.456018\n",
       "              CA         4.368218\n",
       "       C      CA         4.868851\n",
       "Name: feature_1, dtype: float64"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df.groupby('color').expanding(3).feature_1.sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "filter函数的参数是作用于整个组且返回值为True或False的函数，我们可以利用filter函数得到分组后的某些特定组别,如下例中元素个数大于三的分组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>color</th>\n",
       "      <th>date</th>\n",
       "      <th>feature_1</th>\n",
       "      <th>feature_2</th>\n",
       "      <th>size</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>country</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">B</th>\n",
       "      <th>CN</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-01-13</td>\n",
       "      <td>1.308935</td>\n",
       "      <td>-0.493569</td>\n",
       "      <td>M</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-01-20</td>\n",
       "      <td>0.041672</td>\n",
       "      <td>1.014697</td>\n",
       "      <td>L</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>white</td>\n",
       "      <td>2019-01-27</td>\n",
       "      <td>-0.203778</td>\n",
       "      <td>1.742654</td>\n",
       "      <td>M</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CN</th>\n",
       "      <td>black</td>\n",
       "      <td>2019-02-17</td>\n",
       "      <td>-0.649887</td>\n",
       "      <td>-0.187894</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               color       date  feature_1  feature_2 size\n",
       "class country                                             \n",
       "B     CN       white 2019-01-13   1.308935  -0.493569    M\n",
       "      US       black 2019-01-20   0.041672   1.014697    L\n",
       "      US       white 2019-01-27  -0.203778   1.742654    M\n",
       "      CN       black 2019-02-17  -0.649887  -0.187894    S"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df.groupby('class').filter(lambda x: len(x) > 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有些对于分组数据的处理用transform和aggregate都很难完成，这时候我们需要使用apply函数，apply相较两者更加灵活。在apply中可使用用自定义函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "class       \n",
       "A      count    3.000000\n",
       "       mean     0.676204\n",
       "       std      1.804268\n",
       "       min     -1.234449\n",
       "       25%     -0.161125\n",
       "       50%      0.912200\n",
       "       75%      1.631531\n",
       "       max      2.350862\n",
       "B      count    4.000000\n",
       "       mean     0.124235\n",
       "       std      0.840077\n",
       "       min     -0.649887\n",
       "       25%     -0.315306\n",
       "       50%     -0.081053\n",
       "       75%      0.358488\n",
       "       max      1.308935\n",
       "C      count    3.000000\n",
       "       mean    -0.124984\n",
       "       std      1.014446\n",
       "       min     -1.295436\n",
       "       25%     -0.437792\n",
       "       50%      0.419852\n",
       "       75%      0.460243\n",
       "       max      0.500633\n",
       "Name: feature_1, dtype: float64"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df.groupby('class')['feature_1'].apply(lambda x: x.describe())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>demeaned</th>\n",
       "      <th>original</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>country</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>JP</th>\n",
       "      <td>-1.910653</td>\n",
       "      <td>-1.234449</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">B</th>\n",
       "      <th>CN</th>\n",
       "      <td>1.184700</td>\n",
       "      <td>1.308935</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CN</th>\n",
       "      <td>-0.774122</td>\n",
       "      <td>-0.649887</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>-0.082563</td>\n",
       "      <td>0.041672</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>US</th>\n",
       "      <td>-0.328014</td>\n",
       "      <td>-0.203778</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <th>US</th>\n",
       "      <td>0.544836</td>\n",
       "      <td>0.419852</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">A</th>\n",
       "      <th>CN</th>\n",
       "      <td>1.674658</td>\n",
       "      <td>2.350862</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CA</th>\n",
       "      <td>0.235996</td>\n",
       "      <td>0.912200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">C</th>\n",
       "      <th>JP</th>\n",
       "      <td>-1.170452</td>\n",
       "      <td>-1.295436</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CA</th>\n",
       "      <td>0.625616</td>\n",
       "      <td>0.500633</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               demeaned  original\n",
       "class country                    \n",
       "A     JP      -1.910653 -1.234449\n",
       "B     CN       1.184700  1.308935\n",
       "      CN      -0.774122 -0.649887\n",
       "      US      -0.082563  0.041672\n",
       "      US      -0.328014 -0.203778\n",
       "C     US       0.544836  0.419852\n",
       "A     CN       1.674658  2.350862\n",
       "      CA       0.235996  0.912200\n",
       "C     JP      -1.170452 -1.295436\n",
       "      CA       0.625616  0.500633"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def f(group):\n",
    "    return pd.DataFrame({'original' : group,'demeaned' : group - group.mean()})\n",
    "data_df.groupby('class')['feature_1'].apply(f)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 参考文献"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. pandas toolkit\n",
    "2. https://cloud.tencent.com/developer/article/1193823"
   ]
  }
 ],
 "metadata": {
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
